function [NameBlk, EqtnBlk] = blazer(this, varargin)
% blazer  Reorder steady-state equations into block-recursive structure.
%
% Syntax
% =======
%
%     [NameBlk,EqtnBlk] = blazer(M,...)
%
%
% Input arguments
% ================
%
% * `M` [ model ] - Model object.
%
%
% Output arguments
% =================
%
% * `M` [ model ] - Model object with variables and steady-state equations
% regrouped to create block-recursive structure.
%
% * `NameBlk` [ cell ] - Cell of cellstr with variable names in each block.
%
% * `EqtnBlk` [ cell ] - Cell of cellstr with equations in each block.
%
%
% Options
% ========
%
% * `'endogenize='` [ cellstr | char ] - List of parameters that will be
% endogenized in steady equations.
%
% * `'exogenize='` [ cellstr | char ] - List of transition or measurement
% variables that will be exogenized in steady equations.
%
%
% Description
% ============
% 
% The reordering algorithm first identifies equations with a single
% variable in each, and variables occurring in a single equation each, and
% then uses a combination of column and row approximate minimum degree
% permutations (`colamd`) followed by a Dulmage-Mendelsohn permutation
% (`dmperm`).
%
% The output arguments `NameBlk` and `EqtnBlk` are 1-by-N cell arrays,
% where N is the number of blocks, and each cell is a 1-by-Kn cell array of
% strings, where Kn is the number of variables and equations in block N.
%
%
% Example
% ========
%

% -IRIS Toolbox.
% -Copyright (c) 2007-2015 IRIS Solutions Team.

opt = passvalopt('model.blazer', varargin{:});

%--------------------------------------------------------------------------

NameBlk = cell(1,0); %#ok<PREALL>
EqtnBlk = cell(1,0); %#ok<PREALL>

if this.IsLinear
    throw( exception.Blazer.CANNOT_RUN_LINEAR );
    return %#ok<UNRCH>
end

b = Blazer( );
b.Name = this.name;
b.Eqtn = this.eqtn;
b.IxOccur = this.occurS;
b.IxEndg = this.nametype==1 | this.nametype==2;
b.IxCanBeEndg = this.nametype==1 | this.nametype==2 | this.nametype==4;
b.IxEqtn = this.eqtntype==1 | this.eqtntype==2;
if ~isempty(opt.endogenise)
    b = endogenize(b, opt.endogenise);
end
if ~isempty(opt.exogenise)
    b = exogenize(b, opt.exogenise);
end
b = createBlocks(b, true);
if b.IsSingular
    throw( exception.Steady.STRUCTURAL_SINGULARITY );
end
[EqtnBlk, NameBlk] = getHuman(b);

end
